package com.fengwk.cv4j.view;

import com.fengwk.cv4j.factory.ViewFactory;
import com.fengwk.support.exception.BaseException;

/**
 * 变量实现
 * 
 * @author fengwk
 *
 * @param <T>
 */
public class VarImpl<T> implements Var<T> {

	private static final long serialVersionUID = -2454496645346553727L;

	/**
	 * 变量值
	 */
	private T value;
	
	/**
	 * 视图工厂
	 */
	private ViewFactory<T> factory;
	
	/**
	 * 当前变量的父级视图
	 */
	private View<T> parent;
	
	/**
	 * 使用视图工厂构造
	 * 
	 * @param factory
	 */
	public VarImpl(ViewFactory<T> factory) {
		this.factory = factory;
	}
	
	/**
	 * 使用一个现有值和视图工厂来构造
	 * 
	 * @param value
	 * @param factory
	 */
	public VarImpl(T value, ViewFactory<T> factory) {
		this.value = value;
		this.factory = factory;
	}
	
	@Override
	public T compute() {
		if (value == null)
			throw new BaseException("value == null");
		
		return value;
	}

	@Override
	public View<T> gradient(View<T> v) {
		if (value == null)
			throw new BaseException("value == null");
		
		if (search(v))
			return factory.of(1, value);
		// 这里不返回一致的0形态是认为0是可以抛弃的形态
		// 所以在实现mul运算时应当注意实现不同类型与Number类型0的运算
		return factory.of(0, value);
	}
	
	@Override
	public String toString() {
		return value.toString();
	}

	@Override
	public String tree() {
		return toString().replaceAll("\n|\r|\\s", "") + "\n";
	}

	@Override
	public void assign(T t) {
		clear();
		this.value = t;
	}

	@Override
	public void parent(View<T> v) {
		this.parent = v;
	}

	@Override
	public void clear() {
		this.value = null;
		if (parent != null && parent instanceof CacheView)
			parent.clear();
	}

	@Override
	public boolean search(View<T> v) {
		return v == this;
	}

}